package com.fessc.develop.job;

import com.fessc.develop.entity.ApplicationPropertiesVo;
import com.fessc.develop.entity.dbvo.TBatchRunJob;
import com.fessc.develop.entity.dbvo.TOrgUrlManage;
import com.fessc.develop.exception.BusinessException;
import com.fessc.develop.model.enums.EnumJobStatus;
import com.fessc.develop.model.enums.EnumTaskCode;
import com.fessc.develop.service.interfaces.ITBatchRunJobService;
import com.fessc.develop.service.interfaces.ITOrgUrlManageService;
import com.fessc.develop.utils.BusiUtil;
import com.fessc.develop.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;

import javax.annotation.Resource;
import java.util.concurrent.ScheduledFuture;


@Slf4j
public abstract class ScheduleJob {

    private String taskCode;

    private String cronExp;

    @Resource
    private ITBatchRunJobService batchRunJobService;

    @Resource
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    @Resource
    private ITOrgUrlManageService orgUrlManageService;

    @Resource
    private ApplicationPropertiesVo applicationPropertiesVo;

    private ScheduledFuture<?> future;

    private class TaskRunnable implements Runnable {
        @Override
        public void run() {
            MDC.put("lodId", BusiUtil.getMDCLogId("", 15));
            TBatchRunJob batchRunJob = batchRunJobService.getJobByTaskCode(getTaskCode());
            if (BusiUtil.isNull(batchRunJob) || BusiUtil.isEquals(batchRunJob.getStatus(), EnumJobStatus.RUNNING.toString())) {
                return;
            }
            Boolean isSuccess = Boolean.TRUE;
            try {
                batchRunJob.setLastRunDate(DateUtil.getCurrentDateTime(DateUtil.DATE_FORMAT)); //记录任务开始日期
                batchRunJob.setLastRunStart(DateUtil.getCurrentDateTime()); //记录任务开始时间
                batchRunJob.setStatus(EnumJobStatus.RUNNING.toString()); //任务状态设置为运行中
                batchRunJobService.updateJobByTaskCode(batchRunJob); //更新数据库

                //考虑事务问题，这里不统一加上事务管理，由具体的业务实现考虑
                execute(); //执行任务

            } catch (BusinessException e) {
                log.error(e.getResult().getMsg(), e);
                isSuccess = Boolean.FALSE;
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                isSuccess = Boolean.FALSE;
            } finally {
                if (isSuccess) {
                    batchRunJob.setStatus(EnumJobStatus.SUCCESS.toString());
                } else {
                    batchRunJob.setStatus(EnumJobStatus.FAILED.toString());
                }
                batchRunJob.setLastRunEnd(DateUtil.getCurrentDateTime());
                batchRunJobService.updateJobByTaskCode(batchRunJob); //更新数据库
            }

        }
    }

    public int getJobBatchtotal(){
        return Integer.parseInt(applicationPropertiesVo.getTaskJobBatchTotal());
    }

    public String getCCBBankId() {
        //获取建行其中一个定时任务对应的机构编码，用于区分建行与其他银行，这样不用在配置文件中定义
        TOrgUrlManage orgUrlManage = orgUrlManageService.getOrgCodeByOrgTypeAndKey("B", EnumTaskCode.CCB_PRE_PAYMENT_PUSH.toString());
        return orgUrlManage == null ? "" : orgUrlManage.getOrgCode();
    }

    public String getTaskTermDate() {
        String date = "";
        try {
            date = DateUtil.getLastDayDate(DateUtil.getCurrentDateTime(), Integer.parseInt(applicationPropertiesVo.getTaskQueryTermDate()));
        } catch (Exception e) {
            log.info("获取查询条件开始日期失败：" + e.getMessage());
        }
        return date;
    }

    public void setCronExp(String cronExp) {

        this.cronExp = cronExp;
    }

    public void startCron() {

        future = threadPoolTaskScheduler.schedule(new TaskRunnable(), new CronTrigger(cronExp));
    }

    public void stopCron() {
        if (future != null) {
            future.cancel(true);
        }
    }

    public abstract String getTaskCode();

    public abstract String execute();

}
